var crypto = require('crypto');
var uuid = require('node-uuid');
var Promise = require('bluebird');
var fs = require('fs');

var chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];

function md5(str) {
    var md5sum = crypto.createHash('md5');
    md5sum.update(str);
    str = md5sum.digest('hex');
    return str;
};

module.exports = {
    /*
    微博短网址原理的算法
    http://www.oschina.net/question/59519_82623

    短网址映射算法的理论（网上找到的资料）

    1)将长网址md5生成32位签名串,分为4段, 每段8个字节; 
    2)对这四段循环处理, 取8个字节, 将他看成16进制串与0x3fffffff(30位1)与操作, 即超过30位的忽略处理; 
    3)这30位分成6段, 每5位的数字作为字母表的索引取得特定字符, 依次进行获得6位字符串; 
    4)总的md5串可以获得4个6位串; 取里面的任意一个就可作为这个长url的短url地址;
    */

    generalShortUrl: function (url) {
        //可以自定义生成MD5加密字符传前的混合KEY   
        var key = "westalgo_author_by_jackli";
        //要使用生成URL的字符   
        var chars = [
            "a", "b", "c", "d", "e", "f", "g", "h",
            "i", "j", "k", "l", "m", "n", "o", "p",
            "q", "r", "s", "t", "u", "v", "w", "x",
            "y", "z", "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "A", "B", "C", "D",
            "E", "F", "G", "H", "I", "J", "K", "L",
            "M", "N", "O", "P", "Q", "R", "S", "T",
            "U", "V", "W", "X", "Y", "Z"

        ];
        //对传入网址进行MD5加密   
        var hex = md5(key + url);

        var resUrl = [];

        for (var i = 0; i < 4; i++) {
            //把加密字符按照8位一组16进制与0x3FFFFFFF进行位与运算   
            var hexint = 0x3FFFFFFF & parseInt("0x" + hex.substring(i * 8, 8), 16);
            var outChars = '';
            for (var j = 0; j < 6; j++) {
                //把得到的值与0x0000003D进行位与运算，取得字符数组chars索引   
                var index = 0x0000003D & hexint;
                //把取得的字符相加   
                outChars += chars[index];
                //每次循环按位右移5位   
                hexint = hexint >> 5;
            }
            //把字符串存入对应索引的输出数组   
            resUrl[i] = outChars;
        }

        return resUrl[0];
    },
    generalUUID: function () {
        return uuid.v4().replace(new RegExp('-', 'gm'), '');
    },
    md5: function (str) {
        var md5sum = crypto.createHash('md5');
        md5sum.update(str);
        str = md5sum.digest('hex');
        return str;
    },

    unique: function (arr) {
        var ret = []
        for (var i = 0; i < arr.length; i++) {
            var item = arr[i]
            if (ret.indexOf(item) === -1) {
                ret.push(item)
            }
        }
        return ret
    },
    readFileMd5: function (path) {
        return new Promise(function (resolve, reject) {
            var start = new Date().getTime();
            var md5sum = crypto.createHash('md5');
            var stream = fs.createReadStream(path);
            stream.on('data', function (chunk) {
                md5sum.update(chunk);
            });
            stream.on('end', function () {
                str = md5sum.digest('hex').toUpperCase();
                console.log('文件:' + path + ',MD5签名为:' + str + '.耗时:' + (new Date().getTime() - start) / 1000.00 + "秒");
                resolve(str);
            });
        });
    },
    getParams: function (params) {
        var transfer_params = {};
        //过滤出参数不为空的内容
        for (var p in params) {
            var name = p; //属性名称 
            var value = params[p]; //属性对应的值 
            if (value !== undefined) {
                transfer_params[name] = params[p];
            }
        }
        return transfer_params;
    }
};